﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using YArchitech.HVAC;
using YArchitech.Plumbing.Model;
using YArchitech.Revit;

namespace YArchitech.Plumbing
{
	public class RecSprinklerHelper
	{
		public RecSprinklerHelper(Autodesk.Revit.DB.Document _doc)
		{
			this.doc = _doc;
		}

		public bool IsLevelFit(Autodesk.Revit.DB.View view, double fitValue)
		{
			bool result;
			try
			{
				PlanViewRange viewRange = (view as ViewPlan).GetViewRange();
                ElementId levelId = viewRange.GetLevelId((PlanViewPlane)2);
                ElementId levelId2 = viewRange.GetLevelId((PlanViewPlane)1);
				Level level = this.doc.GetElementById(levelId) as Level;
				Level level2 = this.doc.GetElementById(levelId2) as Level;
				if (Math.Abs(level.Elevation - level2.Elevation) > fitValue)
				{
					result = true;
				}
				else
				{
					result = false;
				}
			}
			catch
			{
				result = false;
			}
			return result;
		}

		public List<Line> GetLinesByAllBeams(List<BeamModel> beams)
		{
			List<Line> list = new List<Line>();
			foreach (BeamModel beamModel in beams)
			{
				if (beamModel.systemLine != null)
				{
					list.Add(beamModel.systemLine);
				}
			}
			return list;
		}

		public List<Line> GetRangedLines(RectangleRange rr, List<Line> lines)
		{
			List<Line> list = new List<Line>();
			YJKLine hyline = new YJKLine(rr.l1);
			YJKLine hyline2 = new YJKLine(rr.l2);
			YJKLine hyline3 = new YJKLine(rr.l3);
			YJKLine hyline4 = new YJKLine(rr.l4);
			XYZ p = rr.p1;
			XYZ p2 = rr.p2;
			XYZ p3 = rr.p3;
			XYZ p4 = rr.p4;
			foreach (Line line in lines)
			{
				XYZ xyz = (line.Tessellate()[0] - line.Tessellate()[1]).Normalize() * 500.0 / 304.8;
				XYZ xyz2 = line.Tessellate()[0] + xyz;
				XYZ xyz3 = line.Tessellate()[1] - xyz;
				YJKLine hyl = new YJKLine(Line.CreateBound(xyz2, xyz3));
				XYZ point = (line.Tessellate()[0] + line.Tessellate()[1]) / 2.0;
				if (this.IsLineInsected(hyl, rr.l1) && this.IsLineInsected(hyl, rr.l3))
				{
					double distance = hyline2.GetDistance(point);
					double distance2 = hyline4.GetDistance(point);
					if (distance >= 0.5 && distance2 >= 0.5)
					{
						list.Add(line);
					}
				}
				else if (this.IsLineInsected(hyl, rr.l2) && this.IsLineInsected(hyl, rr.l4))
				{
					double distance3 = hyline.GetDistance(point);
					double distance4 = hyline3.GetDistance(point);
					if (distance3 >= 0.5 && distance4 >= 0.5)
					{
						list.Add(line);
					}
				}
			}
			return list;
		}

		public bool IsLineInsected(YJKLine hyl, Line l)
		{
			return hyl.IntersectionPoint(l) != null;
		}

		public List<XYZ> GetInsectPointByRRAndLine(RectangleRange rr, Line l)
		{
			List<XYZ> list = new List<XYZ>();
			XYZ xyz = new YJKLine(rr.l1).IntersectionPoint(l);
			if (xyz != null)
			{
				list.Add(xyz);
			}
			xyz = new YJKLine(rr.l2).IntersectionPoint(l);
			if (xyz != null)
			{
				list.Add(xyz);
			}
			xyz = new YJKLine(rr.l3).IntersectionPoint(l);
			if (xyz != null)
			{
				list.Add(xyz);
			}
			xyz = new YJKLine(rr.l4).IntersectionPoint(l);
			if (xyz != null)
			{
				list.Add(xyz);
			}
			return list;
		}

		public bool IsAreaFit(List<RectangleRange> rrList)
		{
			foreach (RectangleRange rectangleRange in rrList)
			{
				if (rectangleRange.l1.Length * 304.8 > 4000.0 || rectangleRange.l2.Length * 304.8 > 4000.0 || rectangleRange.l3.Length * 304.8 > 4000.0 || rectangleRange.l4.Length * 304.8 > 4000.0)
				{
					return false;
				}
			}
			return true;
		}

		private List<LinkedDocument> GetLinkInstance(Autodesk.Revit.DB.Document doc)
		{
			return doc.GetLinkedDocuments().ToList<LinkedDocument>();
		}

		public List<BeamModel> GetLinkDocBeams(YJKViewRange hyvr, double z)
		{
			List<BeamModel> list = new List<BeamModel>();
			foreach (LinkedDocument linkedDocument in this.doc.GetLinkedDocuments())
			{
				Transform transform = linkedDocument.Transform;
				FilteredElementCollector filteredElementCollector = new FilteredElementCollector(linkedDocument.Document);
				filteredElementCollector.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_StructuralFraming);
				foreach (Element ele in filteredElementCollector)
				{
					BeamModel beamModel = new BeamModel(ele, this.doc, transform, hyvr, z);
					if (beamModel.systemLine != null)
					{
						list.Add(beamModel);
					}
				}
			}
			return list;
		}

		public List<BeamModel> GetAllBeams(YJKViewRange hyvr, double z)
		{
			List<Element> list = new FilteredElementCollector(this.doc).OfCategory(BuiltInCategory.OST_StructuralFraming).OfClass(typeof(FamilyInstance)).ToElements().ToList<Element>();
			List<BeamModel> list2 = new List<BeamModel>();
			foreach (Element ele in list)
			{
				list2.Add(new BeamModel(ele, this.doc, null, hyvr, z));
			}
			list2.AddRange(this.GetLinkDocBeams(hyvr, z));
			return list2;
		}

		public XYZ GetThreePoint(XYZ pt1, XYZ pt2, XYZ pt3)
		{
			XYZ xyz = (pt2 - pt1).Normalize();
			XYZ xyz2 = new XYZ(0.0, 0.0, 1.0).CrossProduct(xyz).Normalize();
			YJKLine hyline = new YJKLine(pt3, pt3 + 100.0 * xyz);
			hyline.MakeUnBound();
			pt3 = hyline.GetProject(pt2);
			pt1.DistanceTo(pt2);
			double num = pt3.DistanceTo(pt2);
			if ((pt2 + xyz2 * num - pt2).AngleTo(pt3 - pt2) > Math.PI*.5)
			{
				xyz2 = -xyz2;
			}
			pt3 = pt2 + num * xyz2;
			return pt3;
		}

		public List<RectangleRange> CutRectangleWithOneLine(Line line, RectangleRange rect)
		{
			List<RectangleRange> list = new List<RectangleRange>();
			try
			{
				List<XYZ> list2 = new List<XYZ>();
				List<Line> list3 = new List<Line>();
				IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
				foreach (Line line2 in rect.lineList)
				{
					SetComparisonResult setComparisonResult = line.Intersect(line2, out intersectionResultArray);
					if (8 == (int)setComparisonResult)
					{
						list3.Add(line2);
						list2.Add(line2.GetEndPoint(0));
						list2.Add(intersectionResultArray.get_Item(0).XYZPoint);
						list2.Add(line2.GetEndPoint(1));
					}
				}
				if (list2.Count == 6 && list3.Count == 2 && (int)list3[0].Intersect(list3[1]) == 4)
				{
					RectangleRange item = new RectangleRange(list2[0], list2[1], list2[4], list2[5]);
					RectangleRange item2 = new RectangleRange(list2[1], list2[2], list2[3], list2[4]);
					list.Add(item);
					list.Add(item2);
				}
				if (list.Count == 0)
				{
					list.Add(rect);
				}
			}
			catch (Exception ex)
			{
				ex.ToString();
				list.Clear();
				list.Add(rect);
			}
			return list;
		}

		public bool IsFitRectangle(RectangleRange rr)
		{
			return rr.l1.Length >= 0.5 && rr.l2.Length >= 0.5;
		}

		public List<RectangleRange> CutRectangleWithLines(List<Line> lines, RectangleRange rectOrigin)
		{
			List<RectangleRange> list = new List<RectangleRange>();
			try
			{
				List<RectangleRange> list2 = new List<RectangleRange>();
				list2.Add(rectOrigin);
				foreach (Line line in lines)
				{
					list.Clear();
					foreach (RectangleRange rect in list2)
					{
						List<RectangleRange> collection = this.CutRectangleWithOneLine(line, rect);
						list.AddRange(collection);
					}
					list2.Clear();
					list2.AddRange(list);
				}
			}
			catch (Exception ex)
			{
				ex.ToString();
				list.Clear();
			}
			return list;
		}

		public List<Parking> GetUnSprayedPakings(List<Parking> parkings, List<SprinklerGroup> sgList)
		{
			List<Line> list = new List<Line>();
			foreach (SprinklerGroup sprinklerGroup in sgList)
			{
				list.Add(sprinklerGroup.systemLine);
			}
			List<Parking> list2 = new List<Parking>();
			List<Line> list3 = new List<Line>();
			List<SprinklerGroup> list4 = new List<SprinklerGroup>();
			if (parkings != null && parkings.Count > 0)
			{
				foreach (Parking parking in parkings)
				{
					bool flag = false;
					foreach (Line line in list)
					{
						Line l = Line.CreateBound(line.Tessellate()[0] - new XYZ(0.0, 0.0, line.Tessellate()[0].Z), line.Tessellate()[1] - new XYZ(0.0, 0.0, line.Tessellate()[1].Z));
						if (this.IsLineCrossRectangle(parking.rr, l))
						{
							flag = true;
							bool flag2 = false;
							foreach (Line line2 in list3)
							{
								if (line == line2)
								{
									flag2 = true;
								}
							}
							if (!flag2)
							{
								list3.Add(line);
							}
						}
					}
					if (!flag)
					{
						list2.Add(parking);
					}
				}
			}
			foreach (Line line3 in list)
			{
				bool flag3 = false;
				foreach (Line line4 in list3)
				{
					if (line3 == line4)
					{
						flag3 = true;
					}
				}
				if (!flag3)
				{
					foreach (SprinklerGroup sprinklerGroup2 in sgList)
					{
						if (sprinklerGroup2.systemLine == line3)
						{
							list4.Add(sprinklerGroup2);
						}
					}
				}
			}
			sgList.Clear();
			sgList.AddRange(list4);
			return list2;
		}

		public List<Parking> MoveSGOnParking(Parking p, List<SprinklerGroup> sgList, List<SprinklerGroup> allSGList, List<Parking> allParking, double multiple, double validMaxVal, double validMinVal)
		{
			List<Parking> list = new List<Parking>();
			if (sgList.Count < 1)
			{
				return list;
			}
			SprinklerGroup nearestSprinklerGroup = this.GetNearestSprinklerGroup(p.rr, allSGList);
			XYZ vector = this.GetVector(nearestSprinklerGroup, p, multiple);
			if (this.IsMovedSGValid(nearestSprinklerGroup, allSGList, vector, validMaxVal, validMinVal) && vector != null)
			{
				allSGList.Remove(nearestSprinklerGroup);
				sgList.Remove(nearestSprinklerGroup);
				if (nearestSprinklerGroup.Move(vector))
				{
					list.AddRange(this.GetSparyingPakings(nearestSprinklerGroup, allParking));
				}
				else
				{
					allSGList.Add(nearestSprinklerGroup);
				}
				sgList.Add(nearestSprinklerGroup);
			}
			return list;
		}

		public bool IsMovedSGValid(SprinklerGroup movingSG, List<SprinklerGroup> sgList, XYZ vector, double validMaxVal, double validMinVal)
		{
			bool result;
			try
			{
				if (validMinVal == 0.0 || validMaxVal == 0.0)
				{
					result = false;
				}
				else
				{
					YJKLine hyline = new YJKLine(movingSG.systemLine);
					XYZ xyz;
					if (movingSG.systemLine.Direction.X != 0.0)
					{
						xyz = new XYZ(-movingSG.systemLine.Direction.Y / movingSG.systemLine.Direction.X, 1.0, 0.0);
					}
					else
					{
						xyz = new XYZ(-1.0, 0.0, 0.0);
					}
					xyz = xyz.Normalize();
					List<SprinklerGroup> list = new List<SprinklerGroup>();
					List<SprinklerGroup> list2 = new List<SprinklerGroup>();
					foreach (SprinklerGroup sprinklerGroup in sgList)
					{
						if (sprinklerGroup != movingSG)
						{
							Line otherLine = Line.CreateUnbound((sprinklerGroup.endPoint + sprinklerGroup.startPoint) / 2.0 - new XYZ(0.0, 0.0, (sprinklerGroup.endPoint.Z + sprinklerGroup.startPoint.Z) / 2.0), xyz);
							XYZ xyz2 = hyline.IntersectionPoint(otherLine);
							if (xyz2 != null)
							{
								if (((sprinklerGroup.endPoint + sprinklerGroup.startPoint) / 2.0 - new XYZ(0.0, 0.0, (sprinklerGroup.endPoint.Z + sprinklerGroup.startPoint.Z) / 2.0) - xyz2).Normalize().DistanceTo(xyz) < 0.01)
								{
									list.Add(sprinklerGroup);
								}
								else
								{
									list2.Add(sprinklerGroup);
								}
							}
						}
					}
					bool flag = false;
					bool flag2 = false;
					if (list.Count > 0)
					{
						using (List<SprinklerGroup>.Enumerator enumerator = list.GetEnumerator())
						{
							while (enumerator.MoveNext())
							{
								SprinklerGroup sprinklerGroup2 = enumerator.Current;
								XYZ xyz3 = movingSG.endPoint - new XYZ(0.0, 0.0, movingSG.endPoint.Z) + vector;
								double num = sprinklerGroup2.systemLine.Distance(xyz3) * 304.8;
								if (num <= validMaxVal && num >= validMinVal)
								{
									flag = true;
								}
							}
							goto IL_296;
						}
					}
					flag = true;
					IL_296:
					if (list2.Count > 0)
					{
						using (List<SprinklerGroup>.Enumerator enumerator = list2.GetEnumerator())
						{
							while (enumerator.MoveNext())
							{
								SprinklerGroup sprinklerGroup3 = enumerator.Current;
								XYZ xyz4 = movingSG.endPoint - new XYZ(0.0, 0.0, movingSG.endPoint.Z) + vector;
								double num2 = sprinklerGroup3.systemLine.Distance(xyz4) * 304.8;
								if (num2 <= validMaxVal && num2 >= validMinVal)
								{
									flag2 = true;
								}
							}
							goto IL_32B;
						}
					}
					flag2 = true;
					IL_32B:
					if (flag && flag2)
					{
						result = true;
					}
					else
					{
						result = false;
					}
				}
			}
			catch
			{
				result = true;
			}
			return result;
		}

		public List<Parking> GetSparyingPakings(SprinklerGroup sg, List<Parking> allParking)
		{
			List<Parking> list = new List<Parking>();
			Line line = Line.CreateBound(sg.systemLine.Tessellate()[0], sg.systemLine.Tessellate()[1]);
			line.MakeUnbound();
			foreach (Parking parking in allParking)
			{
				if (this.IsLineCrossRectangle(parking.rr, line))
				{
					list.Add(parking);
				}
			}
			return list;
		}

		public bool IsLineCrossRectangle(RectangleRange rr, Line l)
		{
			YJKLine hyl = new YJKLine(l);
			return this.IsLineInsected(hyl, rr.l1) || this.IsLineInsected(hyl, rr.l2) || this.IsLineInsected(hyl, rr.l3) || this.IsLineInsected(hyl, rr.l4);
		}

		public XYZ GetVector(SprinklerGroup sg, Parking p, double multiple)
		{
			if (sg.systemLine == null || p.center == null)
			{
				return null;
			}
			YJKLine hyline = new YJKLine(sg.systemLine);
			XYZ xyz;
			if (sg.systemLine.Direction.X != 0.0)
			{
				xyz = new XYZ(-sg.systemLine.Direction.Y / sg.systemLine.Direction.X, 1.0, 0.0);
			}
			else
			{
				xyz = new XYZ(-1.0, 0.0, 0.0);
			}
			XYZ nearestPoint = this.GetNearestPoint(sg.systemLine, p.rr);
			Line otherLine = Line.CreateUnbound(nearestPoint, xyz);
			XYZ xyz2 = hyline.IntersectionPoint(otherLine);
			if (xyz2 != null)
			{
				XYZ vector = nearestPoint - xyz2;
				return this.GetStandVector(vector, multiple);
			}
			return null;
		}

		public XYZ GetNearestPoint(Line l, RectangleRange rr)
		{
			XYZ result = rr.p1;
			double num = double.MaxValue;
			l.MakeUnbound();
			if (l.Distance(rr.p1) < num)
			{
				num = l.Distance(rr.p1);
				result = rr.p1;
			}
			if (l.Distance(rr.p2) < num)
			{
				num = l.Distance(rr.p2);
				result = rr.p2;
			}
			if (l.Distance(rr.p3) < num)
			{
				num = l.Distance(rr.p3);
				result = rr.p3;
			}
			if (l.Distance(rr.p4) < num)
			{
				num = l.Distance(rr.p4);
				result = rr.p4;
			}
			return result;
		}

		public XYZ GetDevationPoint(Line l, RectangleRange rr)
		{
			YJKLine hyline = new YJKLine(l);
			XYZ xyz;
			if (l.Direction.X != 0.0)
			{
				xyz = new XYZ(-l.Direction.Y / l.Direction.X, 1.0, 0.0);
			}
			else
			{
				xyz = new XYZ(-1.0, 0.0, 0.0);
			}
			xyz = xyz.Normalize();
			List<XYZ> list = new List<XYZ>();
			List<XYZ> list2 = new List<XYZ>();
			foreach (XYZ xyz2 in rr.xyzList)
			{
				Line otherLine = Line.CreateUnbound(xyz2 - new XYZ(0.0, 0.0, xyz2.Z), xyz);
				XYZ xyz3 = hyline.IntersectionPoint(otherLine);
				if (xyz3 != null)
				{
					if ((xyz2 - new XYZ(0.0, 0.0, xyz2.Z) - xyz3).Normalize().DistanceTo(xyz) < 0.01)
					{
						list.Add(xyz2);
					}
					else
					{
						list2.Add(xyz2);
					}
				}
			}
			XYZ xyz4 = null;
			double num = double.MinValue;
			XYZ xyz5 = null;
			double num2 = double.MinValue;
			foreach (XYZ xyz6 in list)
			{
				double num3 = l.Distance(xyz6);
				if (num3 > num)
				{
					xyz4 = xyz6;
					num = num3;
				}
			}
			foreach (XYZ xyz7 in list2)
			{
				double num4 = l.Distance(xyz7);
				if (num4 > num2)
				{
					xyz5 = xyz7;
					num2 = num4;
				}
			}
			if (xyz4 == null || xyz5 == null)
			{
				return null;
			}
			if (num < num2)
			{
				return xyz4;
			}
			return xyz5;
		}

		public XYZ GetStandVector(XYZ vector, double multiple)
		{
			double num = Math.Sqrt(vector.X * vector.X + vector.Y * vector.Y);
			XYZ xyz = new XYZ(vector.X * multiple / num, vector.Y * multiple / num, 0.0);
			double num2 = (double)((int)(num / multiple) + 1);
			return new XYZ(xyz.X * num2, xyz.Y * num2, 0.0);
		}

		public SprinklerGroup GetNearestSprinklerGroup(RectangleRange rr, List<SprinklerGroup> sgList)
		{
			double num = double.MaxValue;
			SprinklerGroup result = null;
			foreach (SprinklerGroup sprinklerGroup in sgList)
			{
				double distance = new YJKLine(sprinklerGroup.systemLine).GetDistance(rr.center);
				if (distance < num)
				{
					num = distance;
					result = sprinklerGroup;
				}
			}
			return result;
		}

		public List<Parking> GetInnerParkings(List<Parking> parkingList, RectangleRange rr, double z1, double z2)
		{
			List<Parking> list = new List<Parking>();
			foreach (Parking parking in parkingList)
			{
				if (rr.InsidePolygon(parking.center) && parking.originLocation.Z < z2 && parking.originLocation.Z > z1)
				{
					list.Add(parking);
				}
			}
			return list;
		}

		public List<Parking> GetLinkDocPakings(double z)
		{
			List<Parking> list = new List<Parking>();
			try
			{
				List<LinkedDocument> linkInstance = this.GetLinkInstance(this.doc);
				if (linkInstance.Count > 0)
				{
					foreach (LinkedDocument linkedDocument in linkInstance)
					{
						Transform transform = linkedDocument.Transform;
						FilteredElementCollector filteredElementCollector = new FilteredElementCollector(linkedDocument.Document);
						filteredElementCollector.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_Parking);
						foreach (Element e in filteredElementCollector)
						{
							Parking parking = new Parking(e, z, this.doc, transform);
							if (parking.rr != null && parking.center != null)
							{
								list.Add(parking);
							}
						}
					}
				}
			}
			catch
			{
			}
			return list;
		}

		public List<XYZ> GetRulesPakings(List<XYZ> innerParkingList)
		{
			List<XYZ> list = new List<XYZ>();
			double largestK = this.getLargestK(innerParkingList);
			if (innerParkingList.Count > 0)
			{
				foreach (XYZ xyz in innerParkingList)
				{
					foreach (XYZ xyz2 in innerParkingList)
					{
						if (xyz != xyz2)
						{
							double num;
							if (xyz.X - xyz2.X == 0.0)
							{
								num = 100000.0;
							}
							else
							{
								num = (xyz.Y - xyz2.Y) / (xyz.X - xyz2.X);
							}
							if (Math.Abs(num - largestK) < 0.01)
							{
								bool flag = false;
								using (List<XYZ>.Enumerator enumerator3 = list.GetEnumerator())
								{
									while (enumerator3.MoveNext())
									{
										if (enumerator3.Current == xyz2)
										{
											flag = true;
										}
									}
								}
								if (!flag)
								{
									list.Add(xyz2);
								}
							}
						}
					}
				}
			}
			return list;
		}

		private double getLargestK(List<XYZ> xyzList)
		{
			Dictionary<double, double> dictionary = new Dictionary<double, double>();
			foreach (XYZ xyz in xyzList)
			{
				foreach (XYZ xyz2 in xyzList)
				{
					if (xyz != xyz2)
					{
						double num = 0.0;
						if (xyz.X - xyz2.X == 0.0)
						{
							num = 100000.0;
						}
						else
						{
							num = (xyz.Y - xyz2.Y) / (xyz.X - xyz2.X);
						}
						try
						{
							Dictionary<double, double> dictionary2 = dictionary;
							double key = num;
							double num2 = dictionary2[key];
							dictionary2[key] = num2 + 1.0;
						}
						catch (Exception)
						{
							dictionary.Add(num, 1.0);
						}
					}
				}
			}
			double num3 = 0.0;
			double result = 0.0;
			foreach (KeyValuePair<double, double> keyValuePair in dictionary)
			{
				if (keyValuePair.Value > num3)
				{
					num3 = keyValuePair.Value;
					result = keyValuePair.Key;
				}
			}
			return result;
		}

		public List<XYZ> getEndPoints(List<XYZ> xyzList)
		{
			List<XYZ> list = new List<XYZ>();
			if (xyzList.Count == 0)
			{
				return null;
			}
			if (xyzList.Count == 1)
			{
				list.Add(xyzList[0]);
			}
			else
			{
				double num = double.MinValue;
				Line line = null;
				foreach (XYZ xyz in xyzList)
				{
					foreach (XYZ xyz2 in xyzList)
					{
						if (xyz != xyz2)
						{
							try
							{
								Line line2 = Line.CreateBound(xyz, xyz2);
								if (line2.Length > num)
								{
									line = line2;
									num = line2.Length;
								}
							}
							catch
							{
							}
						}
					}
				}
				if (line != null)
				{
					list.Add(line.Tessellate()[0]);
					list.Add(line.Tessellate()[1]);
				}
			}
			return list;
		}

		public List<ColumnModel> GetAllColumns(double z, YJKViewRange floorRange, RectangleRange rectRange)
		{
			List<ColumnModel> list = new List<ColumnModel>();
			ElementFilter elementFilter = new ElementCategoryFilter(BuiltInCategory.OST_StructuralColumns);
			ElementCategoryFilter elementCategoryFilter = new ElementCategoryFilter(BuiltInCategory.OST_Columns);
			LogicalOrFilter logicalOrFilter = new LogicalOrFilter(elementFilter, elementCategoryFilter);
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.doc);
			filteredElementCollector.WherePasses(logicalOrFilter).OfClass(typeof(FamilyInstance));
			foreach (Element ele in filteredElementCollector)
			{
				ColumnModel columnModel = new ColumnModel(ele, this.doc, null, z, floorRange, rectRange);
				if (columnModel.rr != null)
				{
					list.Add(columnModel);
				}
			}
			List<LinkedDocument> linkInstance = this.GetLinkInstance(this.doc);
			if (linkInstance.Count > 0)
			{
				foreach (LinkedDocument linkedDocument in linkInstance)
				{
					Transform transform = linkedDocument.Transform;
					FilteredElementCollector filteredElementCollector2 = new FilteredElementCollector(linkedDocument.Document);
					filteredElementCollector2.WherePasses(logicalOrFilter).OfClass(typeof(FamilyInstance));
					foreach (Element ele2 in filteredElementCollector2)
					{
						ColumnModel columnModel2 = new ColumnModel(ele2, this.doc, transform, z, floorRange, rectRange);
						if (columnModel2.rr != null)
						{
							list.Add(columnModel2);
						}
					}
				}
			}
			return list;
		}

		public List<SprinklerGroup> GetNextSG(Line systemLine, List<SprinklerGroup> sgList, double validMaxVal, double validMinVal)
		{
			List<SprinklerGroup> result;
			try
			{
				List<SprinklerGroup> list = new List<SprinklerGroup>();
				YJKLine hyline = new YJKLine(systemLine);
				foreach (SprinklerGroup sprinklerGroup in sgList)
				{
					double num = hyline.GetDistance(sprinklerGroup.systemLine) * 304.8;
					if (num > validMinVal && num < validMaxVal)
					{
						list.Add(sprinklerGroup);
					}
				}
				result = list;
			}
			catch
			{
				result = null;
			}
			return result;
		}

		public bool IsSprinklerGroupValid(Line systemLine, List<SprinklerGroup> sgList, double validMaxVal, double validMinVal)
		{
			bool result;
			try
			{
				if (sgList == null || sgList.Count < 1)
				{
					result = true;
				}
				else
				{
					YJKLine hyline = new YJKLine(systemLine);
					foreach (SprinklerGroup sprinklerGroup in sgList)
					{
						double num = hyline.GetDistance(sprinklerGroup.systemLine) * 304.8;
						if (num < validMinVal)
						{
							return false;
						}
						if (num > validMaxVal)
						{
							return false;
						}
					}
					result = true;
				}
			}
			catch
			{
				result = false;
			}
			return result;
		}

		public List<SprinklerGroup> GetConflictSGList(List<SprinklerGroup> sgList, List<ColumnModel> cmList)
		{
			List<SprinklerGroup> list = new List<SprinklerGroup>();
			foreach (SprinklerGroup sprinklerGroup in sgList)
			{
				bool flag = true;
				foreach (ColumnModel columnModel in cmList)
				{
					if (this.IsLineCrossRectangle(columnModel.rr, sprinklerGroup.systemLine))
					{
						sprinklerGroup.conflictCMList.Add(columnModel);
						flag = false;
					}
				}
				if (!flag)
				{
					list.Add(sprinklerGroup);
				}
			}
			return list;
		}

		public void MoveBeamSprinklerGroup(SprinklerGroup sg, List<SprinklerGroup> sgList, double validMaxVal, double validMinVal, double multiple, double dDisSafe)
		{
			List<BeamModel> beamList = sg.beamList;
			if (beamList == null || beamList.Count <= 0)
			{
				return;
			}
			XYZ xyz = null;
			XYZ xyz2 = null;
			double num = 0.0;
			double num2 = 0.0;
			List<BeamModel> list = new List<BeamModel>();
			foreach (BeamModel beamModel in beamList)
			{
				YJKLine hyline = new YJKLine(new XYZ(beamModel.systemLine.Tessellate()[0].X, beamModel.systemLine.Tessellate()[0].Y, 0.0), new XYZ(beamModel.systemLine.Tessellate()[1].X, beamModel.systemLine.Tessellate()[1].Y, 0.0));
				hyline.MakeUnBound();
				YJKLine hyline2 = new YJKLine(new XYZ(sg.startPoint.X, sg.startPoint.Y, 0.0), new XYZ(sg.endPoint.X, sg.endPoint.Y, 0.0));
				if (hyline.IntersectionPoint(hyline2.Line) != null)
				{
					list.Add(beamModel);
				}
				else
				{
					foreach (XYZ xyz3 in sg.sprinklerPosition)
					{
						XYZ xyz4 = new XYZ(xyz3.X, xyz3.Y, 0.0);
						XYZ project = hyline.GetProject(xyz4);
						if (project != null && hyline.IsPointOnLine(project))
						{
							XYZ xyz5 = (xyz4 - project).Normalize();
							if (xyz == null)
							{
								xyz = xyz5;
								num = project.DistanceTo(xyz4) - beamModel.Width / 2.0;
							}
							else if (xyz2 == null && !xyz.IsAlmostEqualTo(xyz5, 0.001))
							{
								xyz2 = xyz5;
								num2 = project.DistanceTo(xyz4) - beamModel.Width / 2.0;
							}
							else if (xyz.IsAlmostEqualTo(xyz5, 0.001) && num < project.DistanceTo(xyz4) + beamModel.Width / 2.0)
							{
								num = project.DistanceTo(xyz4) - beamModel.Width / 2.0;
							}
							else if (xyz2.IsAlmostEqualTo(xyz5, 0.001) && num2 < project.DistanceTo(xyz4) + beamModel.Width / 2.0)
							{
								num2 = project.DistanceTo(xyz4) - beamModel.Width / 2.0;
							}
						}
					}
				}
			}
			List<SprinklerGroup> list2 = new List<SprinklerGroup>();
			foreach (SprinklerGroup sprinklerGroup in sgList)
			{
				if (sprinklerGroup != sg)
				{
					list2.Add(sprinklerGroup);
				}
			}
			if (xyz != null)
			{
				XYZ xyz6 = null;
				double num3 = 0.0;
				num = (Math.Floor(Math.Abs(num)) + 1.0) * multiple;
				num2 = (Math.Floor(Math.Abs(num2)) + 1.0) * multiple;
				if (xyz != null)
				{
					xyz6 = xyz;
					num3 = num;
				}
				if (xyz != null && xyz2 != null)
				{
					if (num < num2)
					{
						xyz6 = xyz;
						num3 = num;
					}
					else
					{
						xyz6 = xyz2;
						num3 = num2;
					}
				}
				if (xyz6 == null || xyz6.IsAlmostEqualTo(XYZ.Zero))
				{
					return;
				}
				XYZ xyz7 = XYZ.Zero;
				while (xyz7.GetLength() < num3)
				{
					xyz7 += multiple * xyz6.Normalize();
				}
				xyz7 += 2.0 * (multiple * xyz6.Normalize());
				Line systemLine = Line.CreateBound(sg.startPoint + xyz7, sg.endPoint + xyz7);
				if (validMinVal != 0.0)
				{
					List<SprinklerGroup> nextSG = this.GetNextSG(systemLine, list2, validMaxVal, validMinVal);
					if (nextSG == null || nextSG.Count < 1 || !this.IsSprinklerGroupValid(systemLine, nextSG, validMaxVal, validMinVal))
					{
						return;
					}
				}
				sg.Move(xyz7);
			}
			try
			{
				foreach (BeamModel beamModel2 in list)
				{
					double num4 = dDisSafe + beamModel2.Width / 2.0;
					num4 = dDisSafe;
					YJKLine hyline3 = new YJKLine(new XYZ(beamModel2.systemLine.Tessellate()[0].X, beamModel2.systemLine.Tessellate()[0].Y, 0.0), new XYZ(beamModel2.systemLine.Tessellate()[1].X, beamModel2.systemLine.Tessellate()[1].Y, 0.0));
					YJKLine hyline4 = new YJKLine(new XYZ(sg.startPoint.X, sg.startPoint.Y, 0.0), new XYZ(sg.endPoint.X, sg.endPoint.Y, 0.0));
					XYZ xyz8 = hyline3.IntersectionPoint(hyline4.Line);
					if (xyz8 != null)
					{
						List<XYZ> list3 = new List<XYZ>();
						List<XYZ> list4 = new List<XYZ>();
						foreach (XYZ xyz9 in sg.sprinklerPosition)
						{
							list3.Add(new XYZ(xyz9.X, xyz9.Y, xyz9.Z));
							list4.Add(new XYZ(xyz9.X, xyz9.Y, 0.0));
						}
						foreach (XYZ xyz10 in list3)
						{
							try
							{
								XYZ xyz11 = new XYZ(xyz10.X, xyz10.Y, 0.0);
								if (xyz8.DistanceTo(xyz11) <= num4)
								{
									YJKLine hyline5 = new YJKLine(sg.systemLine);
									XYZ xyz12 = (hyline5.GetProject(xyz10) - hyline5.GetProject(xyz8)).Normalize();
									if (xyz12 != null)
									{
										if (xyz12.IsAlmostEqualTo(XYZ.Zero))
										{
											if (xyz8.DistanceTo(sg.startPoint) > xyz8.DistanceTo(sg.endPoint))
											{
												xyz12 = sg.startPoint - hyline5.GetProject(xyz8);
											}
											else
											{
												xyz12 = sg.endPoint - hyline5.GetProject(xyz8);
											}
										}
										xyz12 = xyz12.Normalize();
										XYZ xyz13 = XYZ.Zero;
										List<XYZ> disInPoints = this.GetDisInPoints(xyz11, list4, validMaxVal, validMinVal);
										do
										{
											xyz13 += multiple * xyz12.Normalize();
											xyz11 += multiple * xyz12.Normalize();
											if (xyz8.DistanceTo(xyz11) > num4)
											{
												goto IL_751;
											}
										}
										while (this.IsInRangel(xyz11, disInPoints, validMaxVal, validMinVal));
										xyz13 -= multiple * xyz12.Normalize();
										xyz11 -= multiple * xyz12.Normalize();
										IL_751:
										sg.MovePoint(xyz10, xyz13);
									}
								}
							}
							catch
							{
							}
						}
					}
				}
			}
			catch (Exception ex)
			{
				string message = ex.Message;
			}
			list2.Add(sg);
		}

		private List<XYZ> GetDisInPoints(XYZ xPoint, List<XYZ> pointList, double dMax, double dMin)
		{
			List<XYZ> list = new List<XYZ>();
			if (xPoint == null || pointList == null || pointList.Count < 1)
			{
				return list;
			}
			foreach (XYZ xyz in pointList)
			{
				if (!xPoint.IsAlmostEqualTo(xyz, 0.0001) && xPoint.DistanceTo(xyz) < dMax && xPoint.DistanceTo(xyz) > dMin)
				{
					list.Add(xyz);
				}
			}
			return list;
		}

		private bool IsInRangel(XYZ xPoint, List<XYZ> pointList, double dMax, double dMin)
		{
			if (xPoint == null || pointList == null || pointList.Count < 1)
			{
				return true;
			}
			foreach (XYZ xyz in pointList)
			{
				if (xPoint.DistanceTo(xyz) > dMax || xPoint.DistanceTo(xyz) < dMin)
				{
					return false;
				}
			}
			return true;
		}

		public bool MoveAwaySprinklerGroup(SprinklerGroup sg, List<SprinklerGroup> sgList, double validMaxVal, double validMinVal, double multiple)
		{
			List<SprinklerGroup> list = new List<SprinklerGroup>();
			foreach (SprinklerGroup sprinklerGroup in sgList)
			{
				if (sprinklerGroup != sg)
				{
					list.Add(sprinklerGroup);
				}
			}
			XYZ moveVector = this.GetMoveVector(sg, multiple);
			if (moveVector == null)
			{
				return false;
			}
			Line systemLine = Line.CreateBound(sg.startPoint + moveVector, sg.endPoint + moveVector);
			if (validMinVal != 0.0)
			{
				List<SprinklerGroup> nextSG = this.GetNextSG(systemLine, list, validMaxVal, validMinVal);
				if (!this.IsSprinklerGroupValid(systemLine, nextSG, validMaxVal, validMinVal))
				{
					return false;
				}
			}
			sg.Move(moveVector);
			list.Add(sg);
			sgList.Clear();
			sgList.AddRange(list);
			return true;
		}

		public int GetDevationC(XYZ p, Line l)
		{
			XYZ xyz = l.Tessellate()[0];
			XYZ xyz2 = l.Tessellate()[1];
			if (Math.Abs(xyz2.Y - xyz.Y) < 0.0001)
			{
				if (p.Y > xyz.Y)
				{
					return 1;
				}
				return -1;
			}
			else if (Math.Abs(xyz2.X - xyz.X) < 0.0001)
			{
				if (p.X > xyz.X)
				{
					return 1;
				}
				return -1;
			}
			else
			{
				double num = (xyz2.Y - xyz.Y) / (xyz2.X - xyz.X);
				double num2 = xyz.Y - xyz.X * num;
				if (num * p.X + num2 > p.Y)
				{
					return 1;
				}
				return -1;
			}
		}

		public bool SystemDevation(SprinklerGroup sg)
		{
			List<Element> mainPipes = sg.mainPipes;
			foreach (ColumnModel columnModel in sg.conflictCMList)
			{
				Pipe pipe = null;
				XYZ xyz = null;
				double distance = 0.0;
				bool flag = false;
				for (int i = 0; i < mainPipes.Count; i++)
				{
					Pipe pipe2 = mainPipes[i] as Pipe;
					Line line = (pipe2.Location as LocationCurve).Curve as Line;
					Line line2 = Line.CreateBound(line.Tessellate()[0] - new XYZ(0.0, 0.0, line.Tessellate()[0].Z), line.Tessellate()[1] - new XYZ(0.0, 0.0, line.Tessellate()[1].Z));
					if (line2 != null && this.IsLineCrossRectangle(columnModel.rr, line2))
					{
						List<XYZ> insectPointByRRAndLine = this.GetInsectPointByRRAndLine(columnModel.rr, line2);
						if (insectPointByRRAndLine.Count == 2)
						{
							List<Element> sprinklers = sg.sprinklers;
							XYZ devationPoint = this.GetDevationPoint(line2, columnModel.rr);
							if (devationPoint != null)
							{
								this.PipeDevation(pipe2, insectPointByRRAndLine[0], insectPointByRRAndLine[1], (line2.Distance(devationPoint) * 304.8 + (double)columnModel.EdgeDistance) * (double)this.GetDevationC(devationPoint, line2));
								SprinklerGroup sprinklerGroup = new SprinklerGroup(sprinklers, sg.uiDoc);
								mainPipes.Clear();
								mainPipes.AddRange(sprinklerGroup.mainPipes);
								break;
							}
							break;
						}
						else if (insectPointByRRAndLine.Count == 1)
						{
							if (!flag)
							{
								pipe = pipe2;
								xyz = insectPointByRRAndLine[0];
								XYZ devationPoint2 = this.GetDevationPoint(line2, columnModel.rr);
								if (devationPoint2 == null)
								{
									break;
								}
								distance = (line2.Distance(devationPoint2) * 304.8 + (double)columnModel.EdgeDistance) * (double)this.GetDevationC(devationPoint2, line2);
								flag = true;
							}
							else
							{
								List<Element> sprinklers2 = sg.sprinklers;
								XYZ xyz2 = insectPointByRRAndLine[0];
								if (!this.MoveInColumSprinkler(xyz2, xyz, sprinklers2))
								{
									break;
								}
								SprinklerGroup sprinklerGroup2 = new SprinklerGroup(sprinklers2, sg.uiDoc);
								mainPipes.Clear();
								mainPipes.AddRange(sprinklerGroup2.mainPipes);
								flag = false;
								i -= 2;
							}
						}
					}
				}
				if (flag)
				{
					List<Element> sprinklers3 = sg.sprinklers;
					XYZ xyz3 = (sg.startPoint - sg.endPoint).Normalize() * 0.1;
					YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipe);
					if (xyz.DistanceTo(sg.endPoint) < xyz.DistanceTo(sg.startPoint))
					{
						xyz3 *= -1.0;
					}
					XYZ xyz2 = xyz + xyz3;
					if (hypiping.IsPointOnPipingLine(hypiping.GetProject(xyz2)))
					{
						this.PipeDevation3(pipe, xyz, xyz2, distance);
						SprinklerGroup sprinklerGroup3 = new SprinklerGroup(sprinklers3, sg.uiDoc);
						mainPipes.Clear();
						mainPipes.AddRange(sprinklerGroup3.mainPipes);
					}
				}
			}
			return false;
		}

		public bool MoveInColumSprinkler(XYZ sPoint, XYZ ePoint, List<Element> sprinklers)
		{
			YJKLine hyline = new YJKLine(new XYZ(sPoint.X, sPoint.Y, 0.0), new XYZ(ePoint.X, ePoint.Y, 0.0));
			if (sprinklers == null || sprinklers.Count < 1)
			{
				return false;
			}
			foreach (Element element in sprinklers)
			{
				if (element != null && element.IsValidObject && element is FamilyInstance)
				{
					FamilyInstance familyInstance = element as FamilyInstance;
					if (familyInstance.Category.Id.IntegerValue == -2008099)
					{
						XYZ point = (familyInstance.Location as LocationPoint).Point;
						if (hyline.IsPointOnLine(new XYZ(point.X, point.Y, 0.0)))
						{
							XYZ xyz;
							if (point.DistanceTo(sPoint) < point.DistanceTo(ePoint))
							{
								xyz = 1.6404199475065617 * (sPoint - ePoint).Normalize();
								xyz += sPoint;
							}
							else
							{
								xyz = 1.6404199475065617 * (ePoint - sPoint).Normalize();
								xyz += ePoint;
							}
							XYZ xyz2 = xyz.Subtract(new XYZ(point.X, point.Y, 0.0));
							int num = (int)(xyz2.DistanceTo(XYZ.Zero) * 304.8 / 100.0);
							if (num < 1)
							{
								num = 1;
							}
							xyz2 = (double)(num * 100) / 304.8 * xyz2.Normalize();
							ElementTransformUtils.MoveElement(this.doc, familyInstance.Id, xyz2);
							this.doc.Regenerate();
							return true;
						}
					}
				}
			}
			return false;
		}

		public double GetLongestD(RectangleRange rr)
		{
			if (rr.l1.Length > rr.l2.Length)
			{
				return rr.l1.Length;
			}
			return rr.l2.Length;
		}

		private double getPipeDiameter(Pipe pipe)
		{
			return pipe.GetParameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).AsDouble();
		}

		public bool PipeDevation(Pipe pipe, XYZ xyz1, XYZ xyz2, double distance)
		{
			HYPipeConnect hypipeConnect = new HYPipeConnect();
			if (Math.Abs(distance) < 3.0 * this.getPipeDiameter(pipe))
			{
				if (distance < 0.0)
				{
					distance = -3.0 * this.getPipeDiameter(pipe);
				}
				else
				{
					distance = 3.0 * this.getPipeDiameter(pipe);
				}
			}
			return hypipeConnect.NewPipePIANYI(pipe, xyz1, xyz2, distance / 304.8, Math.PI*.5, "偏移", false);
		}

		public bool PipeDevation2(Pipe pipe1, XYZ xyz1, Pipe pipe2, XYZ xyz2, double distance)
		{
			try
			{
				HYPipeConnect hypipeConnect = new HYPipeConnect();
				if (Math.Abs(distance) < 3.0 * this.getPipeDiameter(pipe1))
				{
					if (distance < 0.0)
					{
						distance = -3.0 * this.getPipeDiameter(pipe1);
					}
					else
					{
						distance = 3.0 * this.getPipeDiameter(pipe1);
					}
				}
				if (Math.Abs(distance) < 3.0 * this.getPipeDiameter(pipe2))
				{
					if (distance < 0.0)
					{
						distance = -3.0 * this.getPipeDiameter(pipe2);
					}
					else
					{
						distance = 3.0 * this.getPipeDiameter(pipe2);
					}
				}
				hypipeConnect.NewPipePIANYI(pipe1, xyz1, pipe2, xyz2, distance / 304.8, Math.PI*.5, "偏移");
			}
			catch
			{
				return false;
			}
			return true;
		}

		public bool PipeDevation3(Pipe pipe, XYZ xyz1, XYZ xyz2, double distance)
		{
			HYPipeConnect hypipeConnect = new HYPipeConnect();
			if (Math.Abs(distance) < 3.0 * this.getPipeDiameter(pipe))
			{
				if (distance < 0.0)
				{
					distance = -3.0 * this.getPipeDiameter(pipe);
				}
				else
				{
					distance = 3.0 * this.getPipeDiameter(pipe);
				}
			}
			return hypipeConnect.NewPipePIANYI(pipe, xyz1, distance / 304.8, Math.PI*.5, "偏移", xyz2);
		}

		public XYZ GetMoveVector(SprinklerGroup sg, double multiple)
		{
			YJKLine hyline = new YJKLine(sg.systemLine);
			XYZ xyz = null;
			XYZ xyz2 = null;
			XYZ xyz3 = null;
			XYZ xyz4 = null;
			double num = 0.0;
			double num2 = 0.0;
			foreach (ColumnModel columnModel in sg.conflictCMList)
			{
				XYZ nearFurthestPoint = this.GetNearFurthestPoint(hyline, columnModel.rr);
				if (nearFurthestPoint != null)
				{
					XYZ project = hyline.GetProject(nearFurthestPoint);
					if (xyz == null)
					{
						xyz = (nearFurthestPoint - project).Normalize();
						num = hyline.GetDistance(nearFurthestPoint);
						xyz2 = nearFurthestPoint;
					}
					else if (xyz3 == null)
					{
						xyz3 = (nearFurthestPoint - project).Normalize();
						num2 = hyline.GetDistance(nearFurthestPoint);
						xyz4 = nearFurthestPoint;
					}
					else if (xyz.IsAlmostEqualTo((nearFurthestPoint - project).Normalize(), 0.0001))
					{
						if (num < hyline.GetDistance(nearFurthestPoint))
						{
							num = hyline.GetDistance(nearFurthestPoint);
							xyz2 = nearFurthestPoint;
						}
					}
					else if (xyz3.IsAlmostEqualTo((nearFurthestPoint - project).Normalize(), 0.0001) && num2 < hyline.GetDistance(nearFurthestPoint))
					{
						num2 = hyline.GetDistance(nearFurthestPoint);
						xyz4 = nearFurthestPoint;
					}
				}
			}
			if (xyz2 == null || xyz4 == null)
			{
				return null;
			}
			XYZ xyz5;
			if (num < num2)
			{
				xyz5 = xyz2;
			}
			else
			{
				xyz5 = xyz4;
			}
			YJKLine hyline2 = new YJKLine(sg.systemLine);
			XYZ xyz6;
			if (sg.systemLine.Direction.X != 0.0)
			{
				xyz6 = new XYZ(-sg.systemLine.Direction.Y / sg.systemLine.Direction.X, 1.0, 0.0);
			}
			else
			{
				xyz6 = new XYZ(-1.0, 0.0, 0.0);
			}
			Line otherLine = Line.CreateUnbound(xyz5, xyz6);
			XYZ xyz7 = hyline2.IntersectionPoint(otherLine);
			if (xyz7 != null)
			{
				XYZ vector = xyz5 - xyz7;
				return this.GetStandVector(vector, multiple);
			}
			return null;
		}

		public XYZ GetFurthestPoint(Line l, RectangleRange rr)
		{
			XYZ result = rr.p1;
			double num = double.MinValue;
			l.MakeUnbound();
			if (l.Distance(rr.p1) > num)
			{
				num = l.Distance(rr.p1);
				result = rr.p1;
			}
			if (l.Distance(rr.p2) > num)
			{
				num = l.Distance(rr.p2);
				result = rr.p2;
			}
			if (l.Distance(rr.p3) > num)
			{
				num = l.Distance(rr.p3);
				result = rr.p3;
			}
			if (l.Distance(rr.p4) > num)
			{
				num = l.Distance(rr.p4);
				result = rr.p4;
			}
			return result;
		}

		public XYZ GetNearFurthestPoint(YJKLine hyl, RectangleRange rr)
		{
			XYZ result;
			try
			{
				hyl.MakeUnBound();
				XYZ xyz = null;
				XYZ xyz2 = null;
				double num = 0.0;
				XYZ xyz3 = (rr.p1 - hyl.GetProject(rr.p1)).Normalize();
				double distance = hyl.GetDistance(rr.p1);
				XYZ xyz4 = rr.p1;
				XYZ project = hyl.GetProject(rr.p2);
				if (xyz3.IsAlmostEqualTo((rr.p2 - project).Normalize(), 0.0001))
				{
					if (distance < hyl.GetDistance(rr.p2))
					{
						distance = hyl.GetDistance(rr.p2);
						xyz4 = rr.p2;
					}
				}
				else
				{
					xyz = (rr.p2 - project).Normalize();
					num = hyl.GetDistance(rr.p2);
					xyz2 = rr.p2;
				}
				project = hyl.GetProject(rr.p3);
				if (xyz3.IsAlmostEqualTo((rr.p3 - project).Normalize(), 0.0001))
				{
					if (distance < hyl.GetDistance(rr.p3))
					{
						distance = hyl.GetDistance(rr.p3);
						xyz4 = rr.p3;
					}
				}
				else if (xyz == null)
				{
					xyz = (rr.p3 - project).Normalize();
					num = hyl.GetDistance(rr.p3);
					xyz2 = rr.p3;
				}
				else if (xyz.IsAlmostEqualTo((rr.p3 - project).Normalize(), 0.0001) && num < hyl.GetDistance(rr.p3))
				{
					num = hyl.GetDistance(rr.p3);
					xyz2 = rr.p3;
				}
				project = hyl.GetProject(rr.p4);
				if (xyz3.IsAlmostEqualTo((rr.p4 - project).Normalize(), 0.0001))
				{
					if (distance < hyl.GetDistance(rr.p4))
					{
						distance = hyl.GetDistance(rr.p4);
						xyz4 = rr.p4;
					}
				}
				else if (xyz == null)
				{
					xyz = (rr.p4 - project).Normalize();
					num = hyl.GetDistance(rr.p4);
					xyz2 = rr.p4;
				}
				else if (xyz.IsAlmostEqualTo((rr.p4 - project).Normalize(), 0.0001) && num < hyl.GetDistance(rr.p4))
				{
					num = hyl.GetDistance(rr.p4);
					xyz2 = rr.p4;
				}
				if (xyz2 == null)
				{
					result = null;
				}
				else if (distance < num)
				{
					result = xyz4;
				}
				else
				{
					result = xyz2;
				}
			}
			catch
			{
				result = null;
			}
			return result;
		}

		private Document doc;
	}
}
